package pt.iul.dcti.poo.financemanager.accounts;

import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Scanner;

import pt.iul.dcti.poo.financemanager.categories.Category;
import pt.iul.dcti.poo.financemanager.date.Date;

public abstract class Account {

	protected long id;
	protected String name;
	private String additionalInfo;
	private double currentBalance;
	private Date startDate;
	private Date endDate;

	protected ArrayList<StatementLine> listaMovimentos = new ArrayList<StatementLine>();

	public Account(long id, String name){
		this.id = id;
		this.name = name;
	}

	public Account(long id, String name, String additionalInfo, double currentBalance, Date startDate, Date endDate, ArrayList<StatementLine> listaMovimentos) {
		super();
		this.id = id;
		this.name = name;
		this.additionalInfo = additionalInfo;
		this.currentBalance = currentBalance;
		this.startDate = startDate;
		this.endDate = endDate;
		this.listaMovimentos=listaMovimentos;
	}

	public static  Account newAccount(File file){
		long newId = 0;
		String newName = null ;
		String newAdditionalInfo = null ;
		String[] line11 = null ;
		Date newStartDate = null ;
		Date newEndDate = null;

		ArrayList<StatementLine> listaMovimentos = new ArrayList<StatementLine>();

		try {
			Scanner s = new Scanner(file);	
			String line0 = s.nextLine(); //passa para a linha seguinte

			//String[] line00 = line0.split("- ");

			/*String[] dataS = line00[1].split("-");
			int diaS = Integer.parseInt(dataS[0]);
			int mesS = Integer.parseInt(dataS[1]);
			int anoS = Integer.parseInt(dataS[2].trim());
			Date accountInfo = new Date(diaS, mesS, anoS);*/

			String line1 = s.nextLine();
			line11 = line1.split(";");
			newId=Long.valueOf(line11[1].trim());
			newName=line11[3].trim();
			//newAdditionalInfo=line11[5].trim();

			String line2 = s.nextLine();
			String[] line22 = line2.split(";");

			String[] dataE = line22[1].split("-");
			int diaE = Integer.parseInt(dataE[0]);
			int mesE = Integer.parseInt(dataE[1]);
			int anoE = Integer.parseInt(dataE[2].trim());
			newStartDate = new Date(diaE, mesE, anoE);

			String line3=s.nextLine();
			String[] line33 = line3.split(";");

			String[] dataN = line33[1].split("-");
			int diaN = Integer.parseInt(dataN[0]);
			int mesN = Integer.parseInt(dataN[1]);
			int anoN = Integer.parseInt(dataN[2].trim());
			newEndDate = new Date(diaN, mesN, anoN);

			String line4=s.nextLine();
			String[] line44 = line4.split(";");

			while(s.hasNextLine()){
				String p = s.nextLine();
				String[] a = p.trim().split(";");

				String[] datas = a[0].split("-");
				int dias = Integer.parseInt(datas[0]);
				int mess = Integer.parseInt(datas[1]);
				int anos = Integer.parseInt(datas[2].trim());
				Date newDate = new Date(dias, mess, anos);

				String[] datas1 = a[1].split("-");
				int dias1 = Integer.parseInt(datas1[0]);
				int mess1 = Integer.parseInt(datas1[1]);
				int anos1 = Integer.parseInt(datas1[2].trim());
				Date newValueDate = new Date(dias1, mess1, anos1);
				// Assuming categories (in this order):
				//SUMMARY with description SUMMARY 
				//SAVINGS with description TRANSF 
				//HOME with descriptions PURCHASE, INSTALMENT
				//CAR with description LOW VALUE
				Category cat = null;
				cat = getCategory(a, cat);
				StatementLine movimento = new StatementLine(newDate, newValueDate, a[2].trim(), Double.valueOf(a[3].trim()), Double.valueOf(a[4].trim()), Double.valueOf(a[5].trim()), Double.valueOf(a[6].trim()), cat);
				listaMovimentos.add(movimento);
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}

		if(line11[4].equals("VIPAccount")){	
			return new DraftAccount(newId, newName, newAdditionalInfo, listaMovimentos.get(listaMovimentos.size()).getAvailableBalance() , newStartDate, newEndDate, listaMovimentos);
		}
		else if(line11[4].equals("DraftAccount")){
			return new DraftAccount(newId, newName, newAdditionalInfo, listaMovimentos.get(listaMovimentos.size()).getAvailableBalance() , newStartDate, newEndDate, listaMovimentos);
		}
		else{
			return new SavingsAccount(newId, newName, newAdditionalInfo, listaMovimentos.get(listaMovimentos.size()-1).getAvailableBalance() , newStartDate, newEndDate, listaMovimentos);
		}
	}

	private static Category getCategory(String[] a, Category cat) {
		switch (a[2].trim()) {
		case "SUMMARY":
			cat = new Category("SUMMARY");
			break;
		case "TRANSF":
			cat = new Category("SAVINGS");
			break;
		case "PURCHASE":
			cat = new Category("HOME");
			break;
		case "INSTALMENT":
			cat = new Category("HOME");
			break;
		case "LOW VALUE":
			cat = new Category("CAR");
			break;
		default:
			break;
		}
		return cat;
	}	

	public long getId() {
		return id;
	}

	public String getName() {
		return name;
	}

	public String additionalInfo(){
		return additionalInfo;
	}

	public double currentBalance() {
		return currentBalance;
	}

	public abstract double estimatedAverageBalance(); //nao corre sempre bem

	public Date getStartDate() {	
		return startDate;
	}

	public Date getEndDate() {
		return endDate;
	}

	public abstract double getInterestRate();

	public void addStatementLine(StatementLine statementLine) {
		listaMovimentos.add(statementLine);
		if(listaMovimentos.size() == 1){
			startDate = listaMovimentos.get(0).getDate();
			endDate = listaMovimentos.get(0).getDate();
			currentBalance = listaMovimentos.get(0).getAvailableBalance();
		}else{
			startDate = listaMovimentos.get(0).getDate();
			endDate = listaMovimentos.get(listaMovimentos.size()-1).getDate();
			currentBalance = listaMovimentos.get(listaMovimentos.size()-1).getAvailableBalance();
		}
	}

	public void setId(long id){
		this.id = id;
	}

	public void setName(String string){
		name = string;
	}

	public ArrayList<StatementLine> getListaMovimentos() {
		return listaMovimentos;
	}

	public void setListaMovimentos(ArrayList<StatementLine> listaMovimentos) {
		this.listaMovimentos = listaMovimentos;
	}

	public double totalForCategory(Category cat, Date date) {
		double somaCategorias = 0;
		for(int i = 0; i < listaMovimentos.size(); i++){
			if(listaMovimentos.get(i).getDate().equals(date) && listaMovimentos.get(i).getCategory().equals(cat)){
				somaCategorias = somaCategorias + listaMovimentos.get(i).getDraft();
			}
		}
		return somaCategorias;
	}

	public void removeStatementLinesBefore(Date date){
		Iterator<StatementLine> i = getListaMovimentos().iterator();
		StatementLine current = i.next();
		while (i.hasNext()) {
		   if(current.getDate().before(date))
			   i.remove();
		   current = i.next();
		}
		
	}

	public double totalForMonth(int month, int year) { 
		double total = 0; 
		for(int i = 0; i < listaMovimentos.size(); i++){ 
			if(listaMovimentos.get(i).getDate().getMonth().ordinal() == month && listaMovimentos.get(i).getDate().getYear() == year){ 
				total = total + listaMovimentos.get(i).getDraft(); 
			} 
		} 
		return total; 
	}

	public void autoCategorizeStatements(List<Category> categories) {
		// TODO Auto-generated method stub
	}

	public double totalDraftsForCategorySince(Category cat, Date date) {
		double total = 0.0;
		for (StatementLine statement : getListaMovimentos()) {
			if(statement.getCategory().equals(cat) && statement.getDate().after(date))
				total = total + statement.getDraft();
		}
//		for(int i = 0; i < listaMovimentos.size(); i++){
//			if(listaMovimentos.get(i).getCategory().equals(cat) && listaMovimentos.get(i).getDate().after(date)){
//				total = total + listaMovimentos.get(i).getDraft();
//			}
//		}
//		return 0.0;
		return total;
	}
	
	
	@Override
	public String toString() {
		return "Account [id=" + id + ", name=" + name + ", additionalInfo="
				+ additionalInfo + ", currentBalance=" + currentBalance
				+ ", startDate=" + startDate + ", endDate=" + endDate
				+ ", listaMovimentos=" + listaMovimentos + "]";
	}

}
